/*
 * Copyright 2011-2012 Redia A/S
 * 
 * This file is part of Indhold+ for Android.
 *
 *  Redia Library App for Android is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Redia Library App for Android is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with Redia Library App for Android.  If not, see <http://www.gnu.org/licenses/>.
 */
package dk.redia.digiform.xmlrpc;

import java.util.Map;

import dk.redia.digiform.model.AdhlObject;
import dk.redia.digiform.model.DigiformObject;
import dk.redia.digiform.model.DigiformRecord;
import dk.redia.lib.log.Log;
import dk.redia.lib.xmlrpc.XmlRpcResultUtils;

public class ResultDecoder {
	private static final String logTag = "DigiformObject";

	@SuppressWarnings("unchecked")
	public static DigiformObject decode(Object xmlRpcDataObj) {
		Map<String, Object> xmlRpcDataObjMap;
		DigiformObject result = new DigiformObject();
		try {
			xmlRpcDataObjMap = (Map<String, Object>)xmlRpcDataObj;
		} catch (ClassCastException e) {
			Log.e(logTag, "Failed to decode XML-RPC response data");
			return null;
		}
		
		// Handling ebooks
		Object ebooksObj = xmlRpcDataObjMap.get("eBooks");
		if (ebooksObj!=null) {
			Object[] ebooksObjArr = XmlRpcResultUtils.unpackArray(ebooksObj);
			if (ebooksObjArr!=null) {
				for (Object ebookObj : ebooksObjArr) {
					Map<String, Object> ebookObjMap = XmlRpcResultUtils.unpackStruct(ebookObj);
					if (ebookObjMap!=null) {
						DigiformRecord eb = new DigiformRecord(ebookObjMap);
						result.addEbook(eb);
					} else {
						Log.e(logTag, "Failed to decode ebook entry in XML-RPC response data");
					}
				}
			}
		}
		
		// Handling record entry
		Object recordObj = xmlRpcDataObjMap.get("record");
		if (recordObj!=null) {
			Map<String, Object> recordObjMap = XmlRpcResultUtils.unpackStruct(recordObj);
			if (recordObjMap!=null) {
				DigiformRecord rec = new DigiformRecord(recordObjMap);
				result.setRecord(rec);
			} else {
				Log.e(logTag, "Failed to decode record entry in XML-RPC response data");
			}
		}
		
		// Handling audioBook entry
		Object audioBookObj = xmlRpcDataObjMap.get("audioBooks");
		if (audioBookObj!=null) {
			Object[] audioBookObjArr;
			try {
				audioBookObjArr = (Object[])audioBookObj;
				
				for (Object audioBookObjObj : audioBookObjArr) {
					Map<String, Object> audioBookObjMap = XmlRpcResultUtils.unpackStruct(audioBookObjObj);
					DigiformRecord ab = new DigiformRecord(audioBookObjMap);
					result.addAudioBook(ab);
				}
				
			} catch (ClassCastException e) {
				Log.e(logTag, "Failed to decode audioBook entry in XML-RPC response data");
			}
			

		}

		// Handling moreOfSameCreator
		Object moreOfSameCreatorObj = xmlRpcDataObjMap.get("moreOfSameCreator");
		if (moreOfSameCreatorObj!=null) {
			Object[] moreOfSameCreatorArr;
			try {
				moreOfSameCreatorArr = (Object[])moreOfSameCreatorObj;				
				for (Object moreOfSameCreatorArrObj : moreOfSameCreatorArr) {
					Object[] moreOfSameCreatorArrArr = XmlRpcResultUtils.unpackArray(moreOfSameCreatorArrObj);
					for (Object moreOfSameCreatorObjObj : moreOfSameCreatorArrArr) {
						Map<String, Object> moreOfSameCreatorObjMap = XmlRpcResultUtils.unpackStruct(moreOfSameCreatorObjObj);
						DigiformRecord mosc = new DigiformRecord(moreOfSameCreatorObjMap);
						result.addMoreOfSameCreator(mosc);
					}
				}
				
			} catch (ClassCastException e) {
				Log.e(logTag, "Failed to decode moreOfSameCreator entry in XML-RPC response data");
			}
		}
		
		// Handling moreFromSame
		Object moreFromSameSeriesObj = xmlRpcDataObjMap.get("moreFromSameSeries");
		if (moreFromSameSeriesObj!=null) {
			Object[] moreFromSameSeriesObjArr1 = XmlRpcResultUtils.unpackArray(moreFromSameSeriesObj);
			if (moreFromSameSeriesObjArr1!=null) {
				for (Object moreFromSameSeriesObj1 : moreFromSameSeriesObjArr1) {
					Object[] moreFromSameSeriesObjArr2 = XmlRpcResultUtils.unpackArray(moreFromSameSeriesObj1);
					if (moreFromSameSeriesObjArr2!=null) {
						for (Object moreFromSameSeriesObj2 : moreFromSameSeriesObjArr2) {
							Map<String, Object> moreFromSameSeriesObjMap = XmlRpcResultUtils.unpackStruct(moreFromSameSeriesObj2);
							if (moreFromSameSeriesObjMap!=null) {
								DigiformRecord mfss = new DigiformRecord(moreFromSameSeriesObjMap);
								result.addMoreFromSameSeries(mfss);
							}
						}
					}
				}
			}
		}
		
		// Handling adhl
		Object adhlObj = xmlRpcDataObjMap.get("adhl");
		if (adhlObj!=null) {
			Object[] adhlObjArr;
			try {
				adhlObjArr = (Object[])adhlObj;
				for (Object adhlObjObj : adhlObjArr) {
					Map<String, Object> adhlObjMap = XmlRpcResultUtils.unpackStruct(adhlObjObj);
					AdhlObject adhlobj = new AdhlObject(adhlObjMap);
					result.addAdhl(adhlobj);
				}
			} catch (ClassCastException e) {
				Log.e(logTag, "Failed to decode adhl entry in XML-RPC response data");
			}
		}
		// NOT handling moreOfSameGenre as it is not needed in the UI
		// Handling relations
		Object relationsObj = xmlRpcDataObjMap.get("relations");
		if (relationsObj!=null) {
			Map<String, Object> relationsMap = XmlRpcResultUtils.unpackStruct(relationsObj);
			if (relationsMap!=null) {
				// NOT handling subjectDescriptions, as they are not needed by the UI
				// Handling reviews
				Object reviewObj = relationsMap.get("reviews");
				if (reviewObj!=null) {
					Object[] reviewsArr = XmlRpcResultUtils.unpackArray(reviewObj);
					if (reviewsArr!=null) {
						for (Object reviewObjObj : reviewsArr) {
							Map<String, Object> reviewObjMap = XmlRpcResultUtils.unpackStruct(reviewObjObj);
							DigiformRecord reviewRecord = new DigiformRecord(reviewObjMap);
							result.addReview(reviewRecord);
						}
					}
				}
				// Handling creatorDescriptions
				Object creatorDescriptionsObj = relationsMap.get("creatorDescriptions");
				if (creatorDescriptionsObj!=null) {
					Object[] creatorDescriptionsArr = XmlRpcResultUtils.unpackArray(creatorDescriptionsObj);
					if (creatorDescriptionsArr!=null) {
						for (Object creatorDescriptionObj : creatorDescriptionsArr) {
							Map<String, Object> creatorDescriptionMap = XmlRpcResultUtils.unpackStruct(creatorDescriptionObj);
							DigiformRecord creatorDescriptionRecord = new DigiformRecord(creatorDescriptionMap);
							result.addCreatorDescription(creatorDescriptionRecord);
						}
					} else {
						Log.e(logTag, "Failed to decode creatorDescriptions entry in XML-RPC response data");
					}
				}
			} else {
				Log.e(logTag, "Failed to decode relations entry in XML-RPC response data");
			}
		}
		
		return result;
	}
}
